package cn.rkylin.oms.system.facade.impl;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import cn.rkylin.core.IDataBaseFactory;
import cn.rkylin.oms.common.context.CurrentUser;
import cn.rkylin.oms.common.context.WebContextFactory;
import cn.rkylin.oms.common.utils.RedisUtils;
import cn.rkylin.oms.system.config.OrgnizationConfig;
import cn.rkylin.oms.system.facade.IOrganizationFacade;
import cn.rkylin.oms.system.facade.ResourceBean;
import cn.rkylin.oms.system.facade.exception.OrgFacadeException;
import cn.rkylin.oms.system.menu.service.IMenuService;
import cn.rkylin.oms.system.privilege.domain.WF_ORG_ROLE_PRIV;
import cn.rkylin.oms.system.project.service.ProjectManagerService;
import cn.rkylin.oms.system.project.vo.ProjectVO;
import cn.rkylin.oms.system.role.vo.RoleVo;
import cn.rkylin.oms.system.unit.domain.WF_ORG_UNIT;
import cn.rkylin.oms.system.unit.service.IUnitService;
import cn.rkylin.oms.system.user.domain.WF_ORG_USER;
import cn.rkylin.oms.system.user.service.IUserService;
import sun.misc.BASE64Encoder;

/**
 * 组织机构权限管理接口
 * 
 * @author 王潇艺
 * @version 1
 */
@Service("orgFacade")
public class OrganizationFacadeImpl implements IOrganizationFacade {

    @Autowired
    protected IDataBaseFactory dao;
    
	/**
	 * 用户业务对象
	 */
	@Autowired
	private IUserService userService;
	
	/**
	 * 组织单元业务对象
	 */
	@Autowired
	private IUnitService unitService;

	/**
	 * 菜单服务
	 */
    @Autowired
    private IMenuService menuService;
    
    @Autowired
    private ProjectManagerService projectManagerService;
    
	/**
	 * 构造函数
	 */
	public OrganizationFacadeImpl() {

	}

	/**
	 * 描述: 根据帐户和密码获取CurrentUser，密码可以是已经加密的，也可以是未加密的。加密使用MD5 算法
	 * 
	 * @param account
	 *            - 帐户（不可为空）
	 * @param password
	 *            - 密码（不可为空）
	 * @param pwdEncrypted
	 *            - 密码是否已经加密
	 * @param needUserUnits
	 *            - 是否需要用户的组织信息
	 * @param needUserStations
	 *            - 是否需要用户的岗位信息
	 * @param needUserRoles
	 *            - 是否需要用户的角色信息
	 * @return 如果用户存在返回CurrentUser，如果用户不存在返回null
	 * @throws OrgFacadeException
	 */
	public CurrentUser getCurrentUser(String account, String password, boolean pwdEncrypted, boolean needUserUnits,
			boolean needUserStations, boolean needUserRoles, boolean needUserExtInfo) throws OrgFacadeException {

        // 帐户和密码不可为空
        if (account == null || account.equals(""))
            throw new OrgFacadeException("参数account不可为空");
        
        // 缓存里有取缓存的，缓存中没有就取db
	    CurrentUser cachedUser = RedisUtils.get("user:" + account, CurrentUser.class);
	    if (cachedUser != null && cachedUser.getPassword().equals(password)) {
	        return cachedUser;
	    }
		
		WF_ORG_USER userParam = new WF_ORG_USER();
		userParam.setUserAccount(account);
		CurrentUser returnUser = this.getCurrentUserByCondition(password, pwdEncrypted, needUserUnits, needUserStations, needUserRoles,
				needUserExtInfo, userParam);
		
		// 放入缓存
		if (returnUser != null) {
		    RedisUtils.set("user:" + account, returnUser, null);
		}
		return returnUser;
	}

	/**
	 * 描述: 根据帐户获取CurrentUser，仅用户信息，没有组织、岗位 、角色信息
	 * 
	 * @param account 帐户
	 * @return 用户Bean
	 * @throws OrgFacadeException
	 */
	public CurrentUser getCurrentUser(String account) throws OrgFacadeException {
		CurrentUser currentUser = null;
		currentUser = getCurrentUser(account, null, false, true, true, true, true);
		return currentUser;
	}

	/**
	 * 方法简要描述信息.
	 * <p>
	 * 描述: 根据帐户获取CurrentUser，仅用户信息，没有组织、岗位 、角色信息
	 * </p>
	 * <p>
	 * 备注: 详见顺序图
	 * </p>
	 * 
	 * @param account
	 *            - 帐户
	 * @return 用户Bean
	 * @throws OrgFacadeException
	 */
	public CurrentUser getCurrentUserById(String id) throws OrgFacadeException {
		CurrentUser currentUser = null;
		currentUser = getCurrentUserById(id, null, false, true, true, true, true);
		return currentUser;
	}

	/**
	 * 创建组织单元
	 * 
	 * @param orgUnit
	 *            不能为空字段：UNIT_ID，PARENT_UNIT_ID, UNIT_NAME
	 * @throws OrgFacadeException
	 */
	public void createOrgUnit(WF_ORG_UNIT orgUnit) throws OrgFacadeException {
		// unitService不可为空
		if (unitService == null)
			throw new OrgFacadeException("OrganizationFacade没有被正确初始化");
		/*
		 * BizTypeDefine bizTypeDefine = OrgnizationConfig
		 * .getBizTypeDefine("unit"); ArrayList list =
		 * bizTypeDefine.getElementList(); String idColumnName = ""; for (int i
		 * = 0; i < list.size(); i++) { ElementDefine ed = (ElementDefine)
		 * list.get(i); if (ed.getName().equalsIgnoreCase("id")) { idColumnName
		 * = ed.getColumn(); break; } }
		 */

		try {
			unitService.saveUnit(orgUnit, "0", null, null);// bizTypeDefine.getTable(),
															// idColumnName);
		} catch (DataAccessException dae) {
			dae.printStackTrace();
			throw new OrgFacadeException("数据库操作错误");
		} catch (Exception e) {
			e.printStackTrace();
			throw new OrgFacadeException("未知错误");
		}
	}

	/**
	 * 更新组织单元
	 * 
	 * @param orgUnit
	 * @throws OrgFacadeException
	 */
	public void updateOrgUnit(WF_ORG_UNIT orgUnit) throws OrgFacadeException {
		// unitService不可为空
		if (unitService == null)
			throw new OrgFacadeException("OrganizationFacade没有被正确初始化");

		try {
			unitService.saveUnit(orgUnit, "1", null, null);
		} catch (DataAccessException dae) {
			dae.printStackTrace();
			throw new OrgFacadeException("数据库操作错误");
		} catch (Exception e) {
			e.printStackTrace();
			throw new OrgFacadeException("未知错误");
		}
	}

	/**
	 * 删除组织单元
	 * 
	 * @param orgUnit
	 * @throws OrgFacadeException
	 */
	public void deleteOrgUnit(WF_ORG_UNIT orgUnit) throws OrgFacadeException {
		// unitService不可为空
		if (unitService == null)
			throw new OrgFacadeException("OrganizationFacade没有被正确初始化");

//		BizTypeDefine bizTypeDefine = OrgnizationConfig.getBizTypeDefine("unit");
//		ArrayList list = bizTypeDefine.getElementList();
//		String idColumnName = "";
//		for (int i = 0; i < list.size(); i++) {
//			ElementDefine ed = (ElementDefine) list.get(i);
//			if (ed.getName().equalsIgnoreCase("id")) {
//				idColumnName = ed.getColumn();
//				break;
//			}
//		}

		try {
			unitService.deleteUnit(orgUnit.getUnitId(), null, null, true);
		} catch (DataAccessException dae) {
			dae.printStackTrace();
			throw new OrgFacadeException("数据库操作错误");
		} catch (Exception e) {
			e.printStackTrace();
			throw new OrgFacadeException("未知错误");
		}

	}

	/**
	 * 方法简要描述信息.
	 * <p>
	 * 描述: 把输入的字符串进行md5加密
	 * </p>
	 * <p>
	 * 备注: 详见顺序图
	 * </p>
	 * 
	 * @param strPassword
	 *            - 未加密的密码
	 * @param strALGORITHM
	 *            - 加密算法
	 * @return 使用md5加密后的密码
	 * @throws Exception
	 */
	private String md5Encrypt(String strPassword, String strALGORITHM) {
		MessageDigest messagedigest = null;
		try {
			messagedigest = MessageDigest.getInstance(strALGORITHM);
		} catch (NoSuchAlgorithmException nosuchalgorithmexception) {
			nosuchalgorithmexception.printStackTrace();
		}
		messagedigest.reset();
		byte abyte0[] = strPassword.getBytes();
		byte abyte1[] = messagedigest.digest(abyte0);
		BASE64Encoder base64encoder = new BASE64Encoder();
		return base64encoder.encode(abyte1);
	}

	public void setIUserService(IUserService userService) {
		this.userService = userService;
	}

	public IUserService getIUserService() {
		return userService;
	}

	public void setIUnitService(IUnitService unitService) {
		this.unitService = unitService;
	}

	public IUnitService getIUnitService() {
		return unitService;
	}

	@Override
	public CurrentUser getCurrentUserById(String Id, String password, boolean pwdEncrypted, boolean needUserUnits,
			boolean needUserStations, boolean needUserRoles, boolean needUserExtInfo) throws OrgFacadeException {

		// 帐户和密码不可为空
		if (Id == null || Id.equals(""))
			throw new OrgFacadeException("参数account不可为空");
		WF_ORG_USER userParam = new WF_ORG_USER();
		userParam.setUserId(Id);
		return this.getCurrentUserByCondition(password, pwdEncrypted, needUserUnits, needUserStations, needUserRoles,
				needUserExtInfo, userParam);
	}

    private CurrentUser getCurrentUserByCondition(String password, boolean pwdEncrypted, boolean needUserUnits, boolean needUserStations,
            boolean needUserRoles, boolean needUserExtInfo, WF_ORG_USER userParam) throws OrgFacadeException {
        // userService不可为空
        if (userService == null)
            throw new OrgFacadeException("OrganizationFacade没有被正确初始化");

        String strPassword = ((password != null && pwdEncrypted) || password == null) ? password
                : md5Encrypt(password, OrgnizationConfig.CRYPTOGRAM_ALGORITHM);
        CurrentUser currentUser = null;
        try {

            userParam.setUserPassword(strPassword);
            List userList = userService.getUserByCondition(userParam, needUserUnits, true, needUserRoles, needUserExtInfo);
            if (userList == null || userList.size() <= 0) {
                currentUser = null;
            } else {
                WF_ORG_USER user = (WF_ORG_USER) userList.get(0);
                if (user != null) {
                    currentUser = new CurrentUser();
                    currentUser.setId(user.getUserId());
                    currentUser.setAccount(user.getUserAccount());
                    currentUser.setCreatedDate(user.getUserAccountCreated());
                    currentUser.setDescription(user.getUserDescription());
                    boolean isEnabled = false;
                    if (user.getUserAccountEnabled() != null && user.getUserAccountEnabled() != "")
                        isEnabled = user.getUserAccountEnabled() == "0" ? false : true;
                    currentUser.setEnabled(isEnabled);
                    // currentUser.setExtendedInfo(jtUser.getExtInfoMap());
                    currentUser.setFullName(user.getUserFullname());
                    boolean isLocked = true;
                    if (user.getUserAccountLocked() != null && user.getUserAccountLocked() != "")
                        isLocked = user.getUserAccountLocked().equals("是") ? true : false;
                    currentUser.setLocked(isLocked);
                    currentUser.setPassword(user.getUserPassword());
                    currentUser.setPwdChangeDate(user.getUserPasswordChanged());
                    currentUser.setRoleList(user.getUserRoleList());
                    currentUser.setStationList(user.getStationList());
                    currentUser.setUnitList(user.getUserUnitList());
                    // 用户的可用菜单项
                    List<ResourceBean> availableMenus = menuService.getUserAvailableMenus(currentUser.getId(), null, true);
                    currentUser.setAvailableMenus(availableMenus);

                    // 用户可以操作的店铺和项目
                    List<String> shopList = null;
                    Map<String, ProjectVO> prjectMap = null;
                    List<String> listRole = new ArrayList<String>();
                    if (user.getUserRoleList() != null && user.getUserRoleList().size() > 0) {
                        for (int i = 0; i < user.getUserRoleList().size(); i++) {
                            RoleVo roleVo = (RoleVo) user.getUserRoleList().get(i);
                            listRole.add(roleVo.getRoleId());
                        }
                        if (listRole != null && listRole.size() > 0) {
                            List listRolePriv = dao.findAllList("selectPrivIdbyRole", listRole);
                            if (listRolePriv != null && listRolePriv.size() > 0) {
                                Map<String, String> mapshop = new HashMap<String, String>();
                                Map<String, String> mapproject = new HashMap<String, String>();
                                shopList = new ArrayList<String>();
                                prjectMap = new HashMap<String, ProjectVO>();
                                for (int i = 0; i < listRolePriv.size(); i++) {
                                    WF_ORG_ROLE_PRIV rolePriv = (WF_ORG_ROLE_PRIV) listRolePriv.get(i);
                                    if ("1".equals(rolePriv.getRolePrivType())) { // shop
                                        if (mapshop.get(rolePriv.getPrivId()) == null) {
                                            mapshop.put(rolePriv.getRolePrivId(), rolePriv.getPrivId());
                                            shopList.add(rolePriv.getPrivId());
                                        }
                                    } else { // project
                                        if (mapproject.get(rolePriv.getPrivId()) == null) {
                                            mapproject.put(rolePriv.getRolePrivId(), rolePriv.getPrivId());
                                            ProjectVO projectParam = new ProjectVO();
                                            projectParam.setPrjId(rolePriv.getPrivId());
                                            List<ProjectVO> prjList = projectManagerService.getSelectProjectsList(projectParam);
                                            if (prjList != null && prjList.size() > 0) {
                                                ProjectVO aProject = prjList.get(0);
                                                prjectMap.put(aProject.getPrjId(), aProject);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    currentUser.setShopIdList(shopList);
                    currentUser.setProjectMap(prjectMap);
                }
            }
        } catch (DataAccessException dae) {
            dae.printStackTrace();
            throw new OrgFacadeException("数据库操作错误");
        } catch (Exception e) {
            e.printStackTrace();
            throw new OrgFacadeException("未知错误");
        }
        return currentUser;
    }
}